In this tutorial, I will walk through a simple program (hello.cc) that initializes cwidget, displays a simple message box, and then terminates the program when the user confirms the message. I assume a basic familiarity with C++. The first thing to do is to include the portions of cwidget that our program will use. Most importantly, we need the
top levelcwidget routines. These are the global routines that initialize cwidget, shut it down, and control its main loop (among other things).
cwidget comes with a collection of stock#include <cwidget/toplevel.h>
dialog boxesfor things like displaying messages to the user. To access the routines that build these dialogs, we write:
All the symbols provided by the cwidget library are in the#include <cwidget/dialogs.h>
cwidget
namespace. Using the full library name means that there's a
reasonable chance that its names will not conflict with the names
provided by other libraries; however, it's a real pain to type
cwidget
over and over. Since this is the only namespaced library we
are using in this program, it's handy to define cw
as an alias for
cwidget
:
Now we're ready to write the main routine. The first interaction of client code with the cwidget library is to initialize it. This will initialize the ncurses library and put the terminal into a mode suitable for a full-screen curses program.namespace cw = cwidget;
Next, we create a dialog box that will be displayed to the user. There are two things to note about this code:cw::toplevel::init();
- cwidget is Unicode-aware and the
ok()
routine expects the message string to be a wide-character string. In this case, that means that we need to pass in a wide-character string (indicated by typing
in front of the string).L
- The second argument tells cwidget what to do when the
ok
button is pressed. The expression
creates a slot using libsigc++. Briefly, a slot is a reference to a function or to a method of a class instance. When invoked, this particular slot will callsigc::ptr_fun(cw::toplevel::exitmain);
cwidget::toplevel::exitmain()
, which causes the main cwidget loop to exit. The slot is wrapped incwidget::util::arg
, a utility function that handles passing slots as optional arguments.
Now that we have a widget, the next step is to arrange for it to appear on the terminal. In cwidget, control of the terminal is assigned to a singlecw::widgets::widget_ref dialog = cw::dialogs::ok(L"Hello, world!", cw::util::arg(sigc::ptr_fun(cw::toplevel::exitmain)));
top-levelwidget: whatever it displays is what gets displayed on the terminal, and all user input is passed directly to it. In a real program this widget will typically manage a collection of sub-widgets and assign each one a screen region, but for now let's just display the dialog box we created:
With everything initialized, we're ready to start the main loop.cw::toplevel::settoplevel(dialog);
mainloop()
will keep the display up-to-date and dispatch incoming
events (for instance, keystrokes and mouse presses) until exitmain()
is invoked.
When the user presses Enter or clicks on the Ok button in the dialog,cw::toplevel::mainloop();
exitmain()
will be invoked by the binding that we set up earlier.
Once this happens, we need to shut down cwidget in order to restore
the terminal to its original state. If you skip this step, the
terminal will be garbled and will not work properly when your program
exits.
And that's it! To compile the program, change to the directory containing hello.cc and run:cw::toplevel::shutdown();
Of course, you'll need to have the g++ and libcwidget-dev packages installed for this to work!$ g++ -o hello hello.cc $(pkg-config --cflags --libs cwidget)